<script setup>
import { ref, watch, nextTick } from 'vue'
import { marked } from 'marked'
const props = defineProps({ messages: Array })
const messagesContainer = ref(null)
function scrollToBottom() { const el = messagesContainer.value; if (el) el.scrollTop = el.scrollHeight }
watch(() => props.messages, async () => { await nextTick(); scrollToBottom() }, { deep: true })

// 渲染输出markdown文本为HTML
marked.setOptions({ breaks: true, gfm: true })
function renderMarkdown(text) { return marked.parse(text || '') }
</script>

<template>
  <div class="messages-container" ref="messagesContainer">
    <div v-if="!messages || messages.length === 0" class="welcome-message">
    </div>

    <div v-for="(m, idx) in messages" :key="m.messageId || m.messageOrder" class="chat-message"
      :class="m.role === 'user' ? 'user-message' : 'ai-message'">
      <div class="message-avatar">
        <div class="avatar" :class="m.role === 'user' ? 'user-avatar' : 'ai-avatar'">{{ m.role === 'user' ? '我' : 'AI'
          }}</div>
      </div>
      <div class="message-content">
        <div class="message-bubble">
          <div v-if="m.role === 'user' && m.fileName" class="file-hint">{{ m.fileName }}</div>
          <div v-if="m.role === 'user'" class="message-text">{{ m.content }}</div>
          <div v-else>
            <div class="message-text message-markdown" v-html="renderMarkdown(m.content)"></div>
            <div v-if="m.streaming" class="typing-dots"><span></span><span></span><span></span></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.messages-container {
  flex: 1;
  overflow: auto;
  padding: 16px;
}

.welcome-message {
  display: grid;
  place-items: center;
  height: 100%;
  color: #555;
}

.welcome-content h2 {
  margin: 0 0 6px;
}

.chat-message {
  display: flex;
  gap: 10px;
  margin-bottom: 12px;
  align-items: flex-start;
}

.user-message {
  flex-direction: row-reverse;
}

.message-avatar {
  width: 40px;
  display: grid;
  place-items: start center;
}

.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
}

.user-avatar {
  background: #333;
  color: #fff;
}

.ai-avatar {
  background: #f0f0f0;
  color: #000;
  border: 1px solid #d0d0d0;
}

.message-content {
  max-width: 70%;
}

.message-bubble {
  background: #f0f0f0;
  border: 1px solid #e1e1e1;
  border-radius: 10px;
  padding: 10px 12px;
  color: #121212;
}

.user-message .message-bubble {
  background: #222222;
  color: #fff;
  border-color: #333333;
}

/* Markdown 样式（轻量） */
.message-markdown :deep(p) { margin: 0 0 8px; line-height: 1.6; }
.message-markdown :deep(code) { background: rgba(0,0,0,.06); padding: 1px 4px; border-radius: 4px; }
.message-markdown :deep(pre) { background: #1e1e1e; color: #eee; padding: 10px; border-radius: 8px; overflow: auto; }
.message-markdown :deep(ul),
.message-markdown :deep(ol) { padding-left: 20px; margin: 6px 0; }
.message-markdown :deep(h1),
.message-markdown :deep(h2),
.message-markdown :deep(h3) { margin: 10px 0 6px; }

.file-hint { font-size: 12px; color: #888; margin-bottom: 6px; }

/* 打字动画（与 App.vue 样式保持一致，组件内独立作用域） */
.typing-dots { display: inline-flex; gap: 4px; align-items: center; margin-top: 6px; }
.typing-dots span { width: 6px; height: 6px; background: #cfcfcf; border-radius: 50%; display: inline-block; animation: blink 1.2s infinite ease-in-out; }
.typing-dots span:nth-child(2) { animation-delay: .2s; }
.typing-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes blink {
  0%, 80%, 100% { opacity: .2 }
  40% { opacity: 1 }
}
</style>
